#include <gtk/gtkentrycompletion.h>
#include <gtk/gtkenums.h>
#include <gtk/gtkeventcontroller.h>
+#include <gtk/gtkeventcontrollerfocus.h>
#include <gtk/gtkeventcontrollerkey.h>
#include <gtk/gtkeventcontrollerlegacy.h>
#include <gtk/gtkeventcontrollermotion.h>
#include "gtkgesturedrag.h"
#include "gtkeventcontrollerscroll.h"
#include "gtkeventcontrollerkey.h"
+#include "gtkeventcontrollerfocus.h"
#include "gtkdragsource.h"
#include "gtknative.h"
#include "gtkicontheme.h"
guint keycode,
GdkModifierType state,
GtkWidget *widget);
-static void gtk_calendar_key_controller_focus (GtkEventController *controller,
- GtkCrossingDirection direction,
+static void gtk_calendar_focus_controller_focus (GtkEventController *controller,
GtkWidget *widget);
static void gtk_calendar_state_flags_changed (GtkWidget *widget,
GtkStateFlags previous_state);
g_signal_connect (controller, "key-pressed",
G_CALLBACK (gtk_calendar_key_controller_key_pressed),
calendar);
- g_signal_connect (controller, "focus-change",
- G_CALLBACK (gtk_calendar_key_controller_focus),
+ gtk_widget_add_controller (GTK_WIDGET (calendar), controller);
+ controller = gtk_event_controller_focus_new ();
+ g_signal_connect (controller, "enter",
+ G_CALLBACK (gtk_calendar_focus_controller_focus),
+ calendar);
+ g_signal_connect (controller, "leave",
+ G_CALLBACK (gtk_calendar_focus_controller_focus),
calendar);
gtk_widget_add_controller (GTK_WIDGET (calendar), controller);
}
static void
-gtk_calendar_key_controller_focus (GtkEventController *controller,
- GtkCrossingDirection direction,
- GtkWidget *widget)
+gtk_calendar_focus_controller_focus (GtkEventController *controller,
+ GtkWidget *widget)
{
GtkCalendar *calendar = GTK_CALENDAR (widget);
GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
#include "gtkentry.h"
#include "gtkmain.h"
#include "gtkmarshalers.h"
+#include "gtkeventcontrollerfocus.h"
#include "gtkeventcontrollerkey.h"
#include "gtkgestureclick.h"
}
static void
-text_focus_change (GtkEntryCompletion *completion,
- GtkCrossingDirection direction)
+text_focus_out (GtkEntryCompletion *completion)
{
- if (direction == GTK_CROSSING_OUT &&
- !gtk_widget_get_mapped (completion->priv->popup_window))
+ if (!gtk_widget_get_mapped (completion->priv->popup_window))
accept_completion_callback (completion);
}
controller = priv->entry_key_controller = gtk_event_controller_key_new ();
g_signal_connect (controller, "key-pressed",
G_CALLBACK (gtk_entry_completion_key_pressed), completion);
- g_signal_connect_swapped (controller, "focus-change", G_CALLBACK (text_focus_change), completion);
+ gtk_widget_add_controller (GTK_WIDGET (text), controller);
+ controller = priv->entry_focus_controller = gtk_event_controller_focus_new ();
+ g_signal_connect_swapped (controller, "leave", G_CALLBACK (text_focus_out), completion);
gtk_widget_add_controller (GTK_WIDGET (text), controller);
completion->priv->changed_id =
GtkText *text = gtk_entry_get_text_widget (GTK_ENTRY (completion->priv->entry));
gtk_widget_remove_controller (GTK_WIDGET (text), completion->priv->entry_key_controller);
+ gtk_widget_remove_controller (GTK_WIDGET (text), completion->priv->entry_focus_controller);
if (completion->priv->changed_id > 0 &&
g_signal_handler_is_connected (text, completion->priv->changed_id))
gchar *case_normalized_key;
GtkEventController *entry_key_controller;
+ GtkEventController *entry_focus_controller;
/* only used by GtkEntry when attached: */
GtkWidget *popup_window;
--- /dev/null
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2020, Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Matthias Clasen <mclasen@redhat.com>
+ */
+
+/**
+ * SECTION:gtkeventcontrollerfocus
+ * @Short_description: Event controller for focus
+ * @Title: GtkEventControllerFocus
+ * @See_also: #GtkEventController
+ *
+ * #GtkEventControllerFocus is an event controller meant for situations
+ * where you need to know where the focusboard focus is.
+ **/
+
+#include "config.h"
+
+#include "gtkintl.h"
+#include "gtkmarshalers.h"
+#include "gtkprivate.h"
+#include "gtkwidgetprivate.h"
+#include "gtkeventcontrollerprivate.h"
+#include "gtkeventcontrollerfocus.h"
+#include "gtkbindings.h"
+#include "gtkenums.h"
+#include "gtkmain.h"
+#include "gtktypebuiltins.h"
+
+#include <gdk/gdk.h>
+
+struct _GtkEventControllerFocus
+{
+ GtkEventController parent_instance;
+
+ const GtkCrossingData *current_crossing;
+
+ guint is_focus : 1;
+ guint contains_focus : 1;
+};
+
+struct _GtkEventControllerFocusClass
+{
+ GtkEventControllerClass parent_class;
+};
+
+enum {
+ ENTER,
+ LEAVE,
+ N_SIGNALS
+};
+
+static guint signals[N_SIGNALS] = { 0 };
+
+enum {
+ PROP_IS_FOCUS = 1,
+ PROP_CONTAINS_FOCUS,
+ NUM_PROPERTIES
+};
+
+static GParamSpec *props[NUM_PROPERTIES] = { NULL, };
+
+G_DEFINE_TYPE (GtkEventControllerFocus, gtk_event_controller_focus,
+ GTK_TYPE_EVENT_CONTROLLER)
+
+static void
+gtk_event_controller_focus_finalize (GObject *object)
+{
+ //GtkEventControllerFocus *focus = GTK_EVENT_CONTROLLER_FOCUS (object);
+
+ G_OBJECT_CLASS (gtk_event_controller_focus_parent_class)->finalize (object);
+}
+
+static void
+update_focus (GtkEventController *controller,
+ const GtkCrossingData *crossing)
+{
+ GtkEventControllerFocus *focus = GTK_EVENT_CONTROLLER_FOCUS (controller);
+ GtkWidget *widget = gtk_event_controller_get_widget (controller);
+ gboolean is_focus = FALSE;
+ gboolean contains_focus = FALSE;
+ gboolean enter = FALSE;
+ gboolean leave = FALSE;
+
+ if (crossing->direction == GTK_CROSSING_IN)
+ {
+ if (crossing->new_target == widget)
+ is_focus = TRUE;
+ if (crossing->new_target != NULL)
+ contains_focus = TRUE;
+ }
+
+ if (focus->contains_focus != contains_focus)
+ {
+ if (contains_focus)
+ enter = TRUE;
+ else
+ leave = TRUE;
+ }
+
+ if (leave)
+ g_signal_emit (controller, signals[LEAVE], 0);
+
+ g_object_freeze_notify (G_OBJECT (focus));
+ if (focus->is_focus != is_focus)
+ {
+ focus->is_focus = is_focus;
+ g_object_notify (G_OBJECT (focus), "is-focus");
+ }
+
+ if (focus->contains_focus != contains_focus)
+ {
+ focus->contains_focus = contains_focus;
+ g_object_notify (G_OBJECT (focus), "contains-focus");
+ }
+ g_object_thaw_notify (G_OBJECT (focus));
+
+ if (enter)
+ g_signal_emit (controller, signals[ENTER], 0);
+}
+
+static void
+gtk_event_controller_focus_handle_crossing (GtkEventController *controller,
+ const GtkCrossingData *crossing,
+ double x,
+ double y)
+{
+ GtkEventControllerFocus *focus = GTK_EVENT_CONTROLLER_FOCUS (controller);
+
+ if (crossing->type != GTK_CROSSING_FOCUS)
+ return;
+
+ focus->current_crossing = crossing;
+
+ update_focus (controller, crossing);
+
+ focus->current_crossing = NULL;
+}
+
+static void
+gtk_event_controller_focus_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkEventControllerFocus *controller = GTK_EVENT_CONTROLLER_FOCUS (object);
+
+ switch (prop_id)
+ {
+ case PROP_IS_FOCUS:
+ g_value_set_boolean (value, controller->is_focus);
+ break;
+
+ case PROP_CONTAINS_FOCUS:
+ g_value_set_boolean (value, controller->contains_focus);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gtk_event_controller_focus_class_init (GtkEventControllerFocusClass *klass)
+{
+ GtkEventControllerClass *controller_class = GTK_EVENT_CONTROLLER_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = gtk_event_controller_focus_finalize;
+ object_class->get_property = gtk_event_controller_focus_get_property;
+ controller_class->handle_crossing = gtk_event_controller_focus_handle_crossing;
+
+ /**
+ * GtkEventControllerFocus:is-focus:
+ *
+ * Whether focus is in the controllers widget itself,
+ * opposed to in a descendent widget. See also
+ * #GtkEventControllerFocus:contains-focus.
+ *
+ * When handling focus events, this property is updated
+ * before #GtkEventControllerFocus::focus-in or
+ * #GtkEventControllerFocus::focus-out are emitted.
+ */
+ props[PROP_IS_FOCUS] =
+ g_param_spec_boolean ("is-focus",
+ P_("Is Focus"),
+ P_("Whether the focus is in the controllers widget"),
+ FALSE,
+ G_PARAM_READABLE);
+
+ /**
+ * GtkEventControllerFocus:contains-focus:
+ *
+ * Whether focus is contain in the controllers widget. See
+ * See #GtkEventControllerFocus:is-focus for whether the focus is in the widget itself
+ * or inside a descendent.
+ *
+ * When handling focus events, this property is updated
+ * before #GtkEventControllerFocus::focus-in or
+ * #GtkEventControllerFocus::focus-out are emitted.
+ */
+ props[PROP_CONTAINS_FOCUS] =
+ g_param_spec_boolean ("contains-focus",
+ P_("Contains Focus"),
+ P_("Whether the focus is in a descendant of the controllers widget"),
+ FALSE,
+ G_PARAM_READABLE);
+
+ g_object_class_install_properties (object_class, NUM_PROPERTIES, props);
+
+ /**
+ * GtkEventControllerFocus::enter:
+ * @controller: the object which received the signal
+ *
+ * This signal is emitted whenever the focus enters into the
+ * widget or one of its descendents.
+ */
+ signals[ENTER] =
+ g_signal_new (I_("enter"),
+ GTK_TYPE_EVENT_CONTROLLER_FOCUS,
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 0);
+
+ /**
+ * GtkEventControllerFocus::leave:
+ * @controller: the object which received the signal
+ *
+ * This signal is emitted whenever the focus leaves from
+ * the widget or one of its descendents.
+ */
+ signals[LEAVE] =
+ g_signal_new (I_("leave"),
+ GTK_TYPE_EVENT_CONTROLLER_FOCUS,
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 0);
+}
+
+static void
+gtk_event_controller_focus_init (GtkEventControllerFocus *controller)
+{
+}
+
+/**
+ * gtk_event_controller_focus_new:
+ *
+ * Creates a new event controller that will handle focus events.
+ *
+ * Returns: a new #GtkEventControllerFocus
+ **/
+GtkEventController *
+gtk_event_controller_focus_new (void)
+{
+ return g_object_new (GTK_TYPE_EVENT_CONTROLLER_FOCUS, NULL);
+}
+
+/**
+ * gtk_event_controller_focus_get_focus_origin:
+ * @controller: a #GtkEventControllerFocus
+ *
+ * Returns the widget that was holding focus before.
+ *
+ * This function can only be used in handlers for the
+ * #GtkEventControllerFocus::focus-in and #GtkEventControllerFocus::focus-out signals.
+ *
+ * Returns: (transfer none): the previous focus
+ */
+GtkWidget *
+gtk_event_controller_focus_get_focus_origin (GtkEventControllerFocus *controller)
+{
+ g_return_val_if_fail (GTK_IS_EVENT_CONTROLLER_FOCUS (controller), NULL);
+ g_return_val_if_fail (controller->current_crossing != NULL, NULL);
+
+ return controller->current_crossing->old_target;
+}
+
+/**
+ * gtk_event_controller_focus_get_focus_target:
+ * @controller: a #GtkEventControllerFocus
+ *
+ * Returns the widget that will be holding focus afterwards.
+ *
+ * This function can only be used in handlers for the
+ * #GtkEventControllerFocus::focus-in and #GtkEventControllerFocus::focus-out signals.
+ *
+ * Returns: (transfer none): the next focus
+ */
+GtkWidget *
+gtk_event_controller_focus_get_focus_target (GtkEventControllerFocus *controller)
+{
+ g_return_val_if_fail (GTK_IS_EVENT_CONTROLLER_FOCUS (controller), NULL);
+ g_return_val_if_fail (controller->current_crossing != NULL, NULL);
+
+ return controller->current_crossing->new_target;
+}
+
+GtkWidget *
+gtk_event_controller_focus_get_old_focus_child (GtkEventControllerFocus *controller)
+{
+ g_return_val_if_fail (GTK_IS_EVENT_CONTROLLER_FOCUS (controller), NULL);
+ g_return_val_if_fail (controller->current_crossing != NULL, NULL);
+
+ return controller->current_crossing->old_descendent;
+}
+
+GtkWidget *
+gtk_event_controller_focus_get_new_focus_child (GtkEventControllerFocus *controller)
+{
+ g_return_val_if_fail (GTK_IS_EVENT_CONTROLLER_FOCUS (controller), NULL);
+ g_return_val_if_fail (controller->current_crossing != NULL, NULL);
+
+ return controller->current_crossing->new_descendent;
+}
+
+/**
+ * gtk_event_controller_focus_contains_focus:
+ * @self: a #GtkEventControllerFocus
+ *
+ * Returns the value of the GtkEventControllerFocus:contains-focus property.
+ *
+ * Returns: %TRUE if focus is within @self or one of its children
+ */
+gboolean
+gtk_event_controller_focus_contains_focus (GtkEventControllerFocus *self)
+{
+ g_return_val_if_fail (GTK_IS_EVENT_CONTROLLER_FOCUS (self), FALSE);
+
+ return self->contains_focus;
+}
+
+/**
+ * gtk_event_controller_focus_is_focus:
+ * @self: a #GtkEventControllerFocus
+ *
+ * Returns the value of the GtkEventControllerFocus:is-focus property.
+ *
+ * Returns: %TRUE if focus is within @self but not one of its children
+ */
+gboolean
+gtk_event_controller_focus_is_focus (GtkEventControllerFocus *self)
+{
+ g_return_val_if_fail (GTK_IS_EVENT_CONTROLLER_FOCUS (self), FALSE);
+
+ return self->is_focus;
+}
--- /dev/null
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2020, Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Matthias Clasen <mclasen@redhat.com>
+ */
+
+#ifndef __GTK_EVENT_CONTROLLER_FOCUS_H__
+#define __GTK_EVENT_CONTROLLER_FOCUS_H__
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#include <gdk/gdk.h>
+#include <gtk/gtkeventcontroller.h>
+#include <gtk/gtkimcontext.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_EVENT_CONTROLLER_FOCUS (gtk_event_controller_focus_get_type ())
+#define GTK_EVENT_CONTROLLER_FOCUS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_EVENT_CONTROLLER_FOCUS, GtkEventControllerFocus))
+#define GTK_EVENT_CONTROLLER_FOCUS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GTK_TYPE_EVENT_CONTROLLER_FOCUS, GtkEventControllerFocusClass))
+#define GTK_IS_EVENT_CONTROLLER_FOCUS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_EVENT_CONTROLLER_FOCUS))
+#define GTK_IS_EVENT_CONTROLLER_FOCUS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GTK_TYPE_EVENT_CONTROLLER_FOCUS))
+#define GTK_EVENT_CONTROLLER_FOCUS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_EVENT_CONTROLLER_FOCUS, GtkEventControllerFocusClass))
+
+typedef struct _GtkEventControllerFocus GtkEventControllerFocus;
+typedef struct _GtkEventControllerFocusClass GtkEventControllerFocusClass;
+
+GDK_AVAILABLE_IN_ALL
+GType gtk_event_controller_focus_get_type (void) G_GNUC_CONST;
+
+GDK_AVAILABLE_IN_ALL
+GtkEventController *gtk_event_controller_focus_new (void);
+
+GDK_AVAILABLE_IN_ALL
+GtkWidget * gtk_event_controller_focus_get_focus_origin (GtkEventControllerFocus *controller);
+GDK_AVAILABLE_IN_ALL
+GtkWidget * gtk_event_controller_focus_get_focus_target (GtkEventControllerFocus *controller);
+GDK_AVAILABLE_IN_ALL
+GtkWidget * gtk_event_controller_focus_get_old_focus_child (GtkEventControllerFocus *controller);
+GDK_AVAILABLE_IN_ALL
+GtkWidget * gtk_event_controller_focus_get_new_focus_child (GtkEventControllerFocus *controller);
+
+GDK_AVAILABLE_IN_ALL
+gboolean gtk_event_controller_focus_contains_focus (GtkEventControllerFocus *self);
+GDK_AVAILABLE_IN_ALL
+gboolean gtk_event_controller_focus_is_focus (GtkEventControllerFocus *self);
+
+
+G_END_DECLS
+
+#endif /* __GTK_EVENT_CONTROLLER_FOCUS_H__ */
GdkModifierType state;
GdkEvent *current_event;
- const GtkCrossingData *current_crossing;
guint is_focus : 1;
guint contains_focus : 1;
KEY_RELEASED,
MODIFIERS,
IM_UPDATE,
- FOCUS_CHANGE,
N_SIGNALS
};
static guint signals[N_SIGNALS] = { 0 };
-enum {
- PROP_IS_FOCUS = 1,
- PROP_CONTAINS_FOCUS,
- NUM_PROPERTIES
-};
-
-static GParamSpec *props[NUM_PROPERTIES] = { NULL, };
-
G_DEFINE_TYPE (GtkEventControllerKey, gtk_event_controller_key,
GTK_TYPE_EVENT_CONTROLLER)
return handled;
}
-static void
-update_focus (GtkEventController *controller,
- const GtkCrossingData *crossing)
-{
- GtkEventControllerKey *key = GTK_EVENT_CONTROLLER_KEY (controller);
- GtkWidget *widget = gtk_event_controller_get_widget (controller);
- gboolean is_focus = FALSE;
- gboolean contains_focus = FALSE;
-
- if (crossing->direction == GTK_CROSSING_IN)
- {
- if (crossing->new_target == widget)
- is_focus = TRUE;
- if (crossing->new_target != NULL)
- contains_focus = TRUE;
- }
-
- g_object_freeze_notify (G_OBJECT (key));
- if (key->is_focus != is_focus)
- {
- key->is_focus = is_focus;
- g_object_notify (G_OBJECT (key), "is-focus");
- if (key->im_context)
- {
- if (is_focus)
- gtk_im_context_focus_in (key->im_context);
- else
- gtk_im_context_focus_out (key->im_context);
- }
- }
- if (key->contains_focus != contains_focus)
- {
- key->contains_focus = contains_focus;
- g_object_notify (G_OBJECT (key), "contains-focus");
- }
- g_object_thaw_notify (G_OBJECT (key));
-}
-
-static void
-gtk_event_controller_key_handle_crossing (GtkEventController *controller,
- const GtkCrossingData *crossing,
- double x,
- double y)
-{
- GtkEventControllerKey *key = GTK_EVENT_CONTROLLER_KEY (controller);
-
- if (crossing->type != GTK_CROSSING_FOCUS)
- return;
-
- key->current_crossing = crossing;
-
- update_focus (controller, crossing);
-
- g_signal_emit (controller, signals[FOCUS_CHANGE], 0, crossing->direction);
-
- key->current_crossing = NULL;
-}
-
-static void
-gtk_event_controller_key_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GtkEventControllerKey *controller = GTK_EVENT_CONTROLLER_KEY (object);
-
- switch (prop_id)
- {
- case PROP_IS_FOCUS:
- g_value_set_boolean (value, controller->is_focus);
- break;
-
- case PROP_CONTAINS_FOCUS:
- g_value_set_boolean (value, controller->contains_focus);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
static void
gtk_event_controller_key_class_init (GtkEventControllerKeyClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = gtk_event_controller_key_finalize;
- object_class->get_property = gtk_event_controller_key_get_property;
controller_class->handle_event = gtk_event_controller_key_handle_event;
- controller_class->handle_crossing = gtk_event_controller_key_handle_crossing;
-
- /**
- * GtkEventControllerKey:is-focus:
- *
- * Whether focus is in the controllers widget itself,
- * opposed to in a descendent widget. See also
- * #GtkEventControllerKey:contains-focus.
- *
- * When handling focus events, this property is updated
- * before #GtkEventControllerKey::focus-in or
- * #GtkEventControllerKey::focus-out are emitted.
- */
- props[PROP_IS_FOCUS] =
- g_param_spec_boolean ("is-focus",
- P_("Is Focus"),
- P_("Whether the focus is in the controllers widget"),
- FALSE,
- G_PARAM_READABLE);
-
- /**
- * GtkEventControllerKey:contains-focus:
- *
- * Whether focus is contain in the controllers widget. See
- * See #GtkEventControllerKey:is-focus for whether the focus is in the widget itself
- * or inside a descendent.
- *
- * When handling focus events, this property is updated
- * before #GtkEventControllerKey::focus-in or
- * #GtkEventControllerKey::focus-out are emitted.
- */
- props[PROP_CONTAINS_FOCUS] =
- g_param_spec_boolean ("contains-focus",
- P_("Contains Focus"),
- P_("Whether the focus is in a descendant of the controllers widget"),
- FALSE,
- G_PARAM_READABLE);
-
- g_object_class_install_properties (object_class, NUM_PROPERTIES, props);
/**
* GtkEventControllerKey::key-pressed:
0, NULL, NULL,
NULL,
G_TYPE_NONE, 0);
-
- /**
- * GtkEventControllerKey::focus-change:
- * @controller: the object which received the signal
- * @direction: the direction of this crossing event
- *
- * This signal is emitted whenever the focus change from or
- * to a widget that is a descendant of the widget to which
- * @controller is attached.
- *
- * Handlers for this signal can use
- * gtk_event_controller_key_get_focus_origin() and
- * gtk_event_controller_key_get_focus_target() to find
- * the old and new focus locations.
- */
- signals[FOCUS_CHANGE] =
- g_signal_new (I_("focus-change"),
- GTK_TYPE_EVENT_CONTROLLER_KEY,
- G_SIGNAL_RUN_LAST,
- 0, NULL, NULL,
- NULL,
- G_TYPE_NONE, 1,
- GTK_TYPE_CROSSING_DIRECTION);
}
static void
return gdk_key_event_get_group (controller->current_event);
}
-
-/**
- * gtk_event_controller_key_get_focus_origin:
- * @controller: a #GtkEventControllerKey
- *
- * Returns the widget that was holding focus before.
- *
- * This function can only be used in handlers for the
- * #GtkEventControllerKey::focus-changed signal.
- *
- * Returns: (transfer none): the previous focus
- */
-GtkWidget *
-gtk_event_controller_key_get_focus_origin (GtkEventControllerKey *controller)
-{
- g_return_val_if_fail (GTK_IS_EVENT_CONTROLLER_KEY (controller), NULL);
- g_return_val_if_fail (controller->current_crossing != NULL, NULL);
-
- return controller->current_crossing->old_target;
-}
-
-/**
- * gtk_event_controller_key_get_focus_target:
- * @controller: a #GtkEventControllerKey
- *
- * Returns the widget that will be holding focus afterwards.
- *
- * This function can only be used in handlers for the
- * #GtkEventControllerKey::focus-changed signal.
- *
- * Returns: (transfer none): the next focus
- */
-GtkWidget *
-gtk_event_controller_key_get_focus_target (GtkEventControllerKey *controller)
-{
- g_return_val_if_fail (GTK_IS_EVENT_CONTROLLER_KEY (controller), NULL);
- g_return_val_if_fail (controller->current_crossing != NULL, NULL);
-
- return controller->current_crossing->new_target;
-}
-
-GtkWidget *
-gtk_event_controller_key_get_old_focus_child (GtkEventControllerKey *controller)
-{
- g_return_val_if_fail (GTK_IS_EVENT_CONTROLLER_KEY (controller), NULL);
- g_return_val_if_fail (controller->current_crossing != NULL, NULL);
-
- return controller->current_crossing->old_descendent;
-}
-
-GtkWidget *
-gtk_event_controller_key_get_new_focus_child (GtkEventControllerKey *controller)
-{
- g_return_val_if_fail (GTK_IS_EVENT_CONTROLLER_KEY (controller), NULL);
- g_return_val_if_fail (controller->current_crossing != NULL, NULL);
-
- return controller->current_crossing->new_descendent;
-}
-
-/**
- * gtk_event_controller_key_contains_focus:
- * @self: a #GtkEventControllerKey
- *
- * Returns the value of the GtkEventControllerKey:contains-focus property.
- *
- * Returns: %TRUE if focus is within @self or one of its children
- */
-gboolean
-gtk_event_controller_key_contains_focus (GtkEventControllerKey *self)
-{
- g_return_val_if_fail (GTK_IS_EVENT_CONTROLLER_KEY (self), FALSE);
-
- return self->contains_focus;
-}
-
-/**
- * gtk_event_controller_key_is_focus:
- * @self: a #GtkEventControllerKey
- *
- * Returns the value of the GtkEventControllerKey:is-focus property.
- *
- * Returns: %TRUE if focus is within @self but not one of its children
- */
-gboolean
-gtk_event_controller_key_is_focus (GtkEventControllerKey *self)
-{
- g_return_val_if_fail (GTK_IS_EVENT_CONTROLLER_KEY (self), FALSE);
-
- return self->is_focus;
-}
GDK_AVAILABLE_IN_ALL
guint gtk_event_controller_key_get_group (GtkEventControllerKey *controller);
-GDK_AVAILABLE_IN_ALL
-GtkWidget * gtk_event_controller_key_get_focus_origin (GtkEventControllerKey *controller);
-GDK_AVAILABLE_IN_ALL
-GtkWidget * gtk_event_controller_key_get_focus_target (GtkEventControllerKey *controller);
-GDK_AVAILABLE_IN_ALL
-GtkWidget * gtk_event_controller_key_get_old_focus_child (GtkEventControllerKey *controller);
-GDK_AVAILABLE_IN_ALL
-GtkWidget * gtk_event_controller_key_get_new_focus_child (GtkEventControllerKey *controller);
-
-GDK_AVAILABLE_IN_ALL
-gboolean gtk_event_controller_key_contains_focus (GtkEventControllerKey *self);
-GDK_AVAILABLE_IN_ALL
-gboolean gtk_event_controller_key_is_focus (GtkEventControllerKey *self);
-
G_END_DECLS
#include "gtkintl.h"
#include "gtkmarshalers.h"
#include "gtkfilefilterprivate.h"
+#include "gtkeventcontrollerfocus.h"
typedef struct _GtkFileChooserEntryClass GtkFileChooserEntryClass;
}
static void
-chooser_entry_focus_change (GtkEventController *controller,
- GtkCrossingDirection direction,
- GtkFileChooserEntry *chooser_entry)
+chooser_entry_focus_out (GtkEventController *controller,
+ GtkFileChooserEntry *chooser_entry)
{
- if (direction == GTK_CROSSING_OUT)
- set_complete_on_load (chooser_entry, FALSE);
+ set_complete_on_load (chooser_entry, FALSE);
}
static void
"key-pressed",
G_CALLBACK (gtk_file_chooser_entry_tab_handler),
chooser_entry);
+ gtk_widget_add_controller (GTK_WIDGET (chooser_entry), controller);
+ controller = gtk_event_controller_focus_new ();
g_signal_connect (controller,
- "focus-change", G_CALLBACK (chooser_entry_focus_change),
+ "leave", G_CALLBACK (chooser_entry_focus_out),
chooser_entry);
gtk_widget_add_controller (GTK_WIDGET (chooser_entry), controller);
#include "gtkactionable.h"
#include "gtkeventcontrollermotion.h"
#include "gtkeventcontrollerkey.h"
+#include "gtkeventcontrollerfocus.h"
#include "gtknative.h"
/**
}
static void
-focus_change_cb (GtkEventController *controller,
- GtkCrossingDirection direction,
- gpointer data)
+focus_in_cb (GtkEventController *controller,
+ gpointer data)
{
GtkWidget *target;
GtkWidget *popover;
- if (direction == GTK_CROSSING_IN)
- {
- target = gtk_event_controller_get_widget (controller);
- popover = gtk_widget_get_ancestor (target, GTK_TYPE_POPOVER_MENU);
+ target = gtk_event_controller_get_widget (controller);
+ popover = gtk_widget_get_ancestor (target, GTK_TYPE_POPOVER_MENU);
- if (popover)
- gtk_popover_menu_set_active_item (GTK_POPOVER_MENU (popover), target);
- }
+ if (popover)
+ gtk_popover_menu_set_active_item (GTK_POPOVER_MENU (popover), target);
}
static void
g_signal_connect (controller, "motion", G_CALLBACK (motion_cb), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
- controller = gtk_event_controller_key_new ();
- g_signal_connect (controller, "focus-change", G_CALLBACK (focus_change_cb), NULL);
+ controller = gtk_event_controller_focus_new ();
+ g_signal_connect (controller, "enter", G_CALLBACK (focus_in_cb), NULL);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
gesture = gtk_gesture_click_new ();
#include "gtkmenutrackerprivate.h"
#include "gtkpopoverprivate.h"
#include "gtkwidgetprivate.h"
-#include "gtkeventcontrollerkey.h"
+#include "gtkeventcontrollerfocus.h"
#include "gtkeventcontrollermotion.h"
#include "gtkmain.h"
#include "gtktypebuiltins.h"
}
static void
-focus_change (GtkEventController *controller,
- GtkCrossingDirection direction,
- GtkPopoverMenu *menu)
+focus_out (GtkEventController *controller,
+ GtkPopoverMenu *menu)
{
GtkWidget *new_focus = gtk_root_get_focus (gtk_widget_get_root (GTK_WIDGET (menu)));
- if (direction == GTK_CROSSING_OUT &&
- !gtk_event_controller_key_contains_focus (GTK_EVENT_CONTROLLER_KEY (controller)) &&
+ if (!gtk_event_controller_focus_contains_focus (GTK_EVENT_CONTROLLER_FOCUS (controller)) &&
new_focus != NULL)
{
if (menu->parent_menu &&
gtk_widget_add_css_class (GTK_WIDGET (popover), "menu");
- controller = gtk_event_controller_key_new ();
- g_signal_connect (controller, "focus-change", G_CALLBACK (focus_change), popover);
+ controller = gtk_event_controller_focus_new ();
+ g_signal_connect (controller, "leave", G_CALLBACK (focus_out), popover);
gtk_widget_add_controller (GTK_WIDGET (popover), controller);
controller = gtk_event_controller_motion_new ();
#include "gtkimage.h"
#include "gtktext.h"
#include "gtkeventcontrollerkey.h"
+#include "gtkeventcontrollerfocus.h"
#include "gtkeventcontrollermotion.h"
#include "gtkeventcontrollerscroll.h"
#include "gtkgestureclick.h"
}
static void
-key_controller_focus_change (GtkEventController *controller,
- GtkCrossingDirection direction,
- GtkSpinButton *spin_button)
+key_controller_focus_out (GtkEventController *controller,
+ GtkSpinButton *spin_button)
{
GtkSpinButtonPrivate *priv = gtk_spin_button_get_instance_private (spin_button);
- if (direction == GTK_CROSSING_OUT &&
- gtk_editable_get_editable (GTK_EDITABLE (priv->entry)))
+ if (gtk_editable_get_editable (GTK_EDITABLE (priv->entry)))
gtk_spin_button_update (spin_button);
}
controller = gtk_event_controller_key_new ();
g_signal_connect (controller, "key-released",
G_CALLBACK (key_controller_key_released), spin_button);
- g_signal_connect (controller, "focus-change",
- G_CALLBACK (key_controller_focus_change), spin_button);
+ gtk_widget_add_controller (GTK_WIDGET (spin_button), controller);
+ controller = gtk_event_controller_focus_new ();
+ g_signal_connect (controller, "leave",
+ G_CALLBACK (key_controller_focus_out), spin_button);
gtk_widget_add_controller (GTK_WIDGET (spin_button), controller);
}
#include "gtkemojichooser.h"
#include "gtkemojicompletion.h"
#include "gtkentrybuffer.h"
+#include "gtkeventcontrollerfocus.h"
#include "gtkeventcontrollerkey.h"
#include "gtkeventcontrollermotion.h"
#include "gtkgesturedrag.h"
int baseline);
static void gtk_text_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot);
-static void gtk_text_focus_change (GtkWidget *widget,
- GtkCrossingDirection direction);
+static void gtk_text_focus_in (GtkWidget *widget);
+static void gtk_text_focus_out (GtkWidget *widget);
static gboolean gtk_text_grab_focus (GtkWidget *widget);
static void gtk_text_css_changed (GtkWidget *widget,
GtkCssStyleChange *change);
G_CALLBACK (gtk_text_key_controller_key_pressed), self);
g_signal_connect_swapped (priv->key_controller, "im-update",
G_CALLBACK (gtk_text_schedule_im_reset), self);
- g_signal_connect_swapped (priv->key_controller, "focus-change",
- G_CALLBACK (gtk_text_focus_change), self);
gtk_event_controller_key_set_im_context (GTK_EVENT_CONTROLLER_KEY (priv->key_controller),
priv->im_context);
gtk_widget_add_controller (GTK_WIDGET (self), priv->key_controller);
+ controller = gtk_event_controller_focus_new ();
+ g_signal_connect_swapped (controller, "enter",
+ G_CALLBACK (gtk_text_focus_in), self);
+ g_signal_connect_swapped (controller, "leave",
+ G_CALLBACK (gtk_text_focus_out), self);
+ gtk_widget_add_controller (GTK_WIDGET (self), controller);
widget_node = gtk_widget_get_css_node (GTK_WIDGET (self));
for (i = 0; i < 2; i++)
}
static void
-gtk_text_focus_change (GtkWidget *widget,
- GtkCrossingDirection direction)
+gtk_text_focus_in (GtkWidget *widget)
{
GtkText *self = GTK_TEXT (widget);
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
GdkKeymap *keymap;
- if (direction == GTK_CROSSING_IN)
- {
- gtk_widget_queue_draw (widget);
+ gtk_widget_queue_draw (widget);
- keymap = gdk_display_get_keymap (gtk_widget_get_display (widget));
+ keymap = gdk_display_get_keymap (gtk_widget_get_display (widget));
- if (priv->editable)
- {
- gtk_text_schedule_im_reset (self);
- gtk_im_context_focus_in (priv->im_context);
- }
+ if (priv->editable)
+ {
+ gtk_text_schedule_im_reset (self);
+ gtk_im_context_focus_in (priv->im_context);
+ }
- g_signal_connect (keymap, "direction-changed",
- G_CALLBACK (keymap_direction_changed), self);
+ g_signal_connect (keymap, "direction-changed",
+ G_CALLBACK (keymap_direction_changed), self);
- gtk_text_reset_blink_time (self);
- gtk_text_check_cursor_blink (self);
- }
- else
- {
- gtk_text_selection_bubble_popup_unset (self);
+ gtk_text_reset_blink_time (self);
+ gtk_text_check_cursor_blink (self);
+}
- if (priv->text_handle)
- _gtk_text_handle_set_mode (priv->text_handle,
- GTK_TEXT_HANDLE_MODE_NONE);
+static void
+gtk_text_focus_out (GtkWidget *widget)
+{
+ GtkText *self = GTK_TEXT (widget);
+ GtkTextPrivate *priv = gtk_text_get_instance_private (self);
+ GdkKeymap *keymap;
- gtk_widget_queue_draw (widget);
+ gtk_text_selection_bubble_popup_unset (self);
- keymap = gdk_display_get_keymap (gtk_widget_get_display (widget));
+ if (priv->text_handle)
+ _gtk_text_handle_set_mode (priv->text_handle,
+ GTK_TEXT_HANDLE_MODE_NONE);
- if (priv->editable)
- {
- gtk_text_schedule_im_reset (self);
- gtk_im_context_focus_out (priv->im_context);
- }
+ gtk_widget_queue_draw (widget);
- gtk_text_check_cursor_blink (self);
+ keymap = gdk_display_get_keymap (gtk_widget_get_display (widget));
- g_signal_handlers_disconnect_by_func (keymap, keymap_direction_changed, self);
+ if (priv->editable)
+ {
+ gtk_text_schedule_im_reset (self);
+ gtk_im_context_focus_out (priv->im_context);
}
+
+ gtk_text_check_cursor_blink (self);
+
+ g_signal_handlers_disconnect_by_func (keymap, keymap_direction_changed, self);
}
static gboolean
static void gtk_text_view_key_controller_im_update (GtkEventControllerKey *controller,
GtkTextView *text_view);
-static void gtk_text_view_focus_change (GtkWidget *widget,
- GtkCrossingDirection direction);
+static void gtk_text_view_focus_in (GtkWidget *widget);
+static void gtk_text_view_focus_out (GtkWidget *widget);
static void gtk_text_view_motion (GtkEventController *controller,
double x,
double y,
g_signal_connect (priv->key_controller, "im-update",
G_CALLBACK (gtk_text_view_key_controller_im_update),
widget);
- g_signal_connect_swapped (priv->key_controller, "focus-change",
- G_CALLBACK (gtk_text_view_focus_change),
- widget);
gtk_event_controller_key_set_im_context (GTK_EVENT_CONTROLLER_KEY (priv->key_controller),
priv->im_context);
gtk_widget_add_controller (widget, priv->key_controller);
+ controller = gtk_event_controller_focus_new ();
+ g_signal_connect_swapped (controller, "enter",
+ G_CALLBACK (gtk_text_view_focus_in), widget);
+ g_signal_connect_swapped (controller, "leave",
+ G_CALLBACK (gtk_text_view_focus_out), widget);
+ gtk_widget_add_controller (widget, controller);
priv->selection_node = gtk_css_node_new ();
gtk_css_node_set_name (priv->selection_node, g_quark_from_static_string ("selection"));
}
static void
-gtk_text_view_focus_change (GtkWidget *widget,
- GtkCrossingDirection direction)
+gtk_text_view_focus_in (GtkWidget *widget)
{
GtkTextView *text_view = GTK_TEXT_VIEW (widget);
GtkTextViewPrivate *priv = text_view->priv;
- if (direction == GTK_CROSSING_IN)
- {
- gtk_widget_queue_draw (widget);
+ gtk_widget_queue_draw (widget);
- DV(g_print (G_STRLOC": focus_in\n"));
+ DV(g_print (G_STRLOC": focus_in\n"));
- gtk_text_view_reset_blink_time (text_view);
+ gtk_text_view_reset_blink_time (text_view);
- if (cursor_visible (text_view) && priv->layout)
- {
- gtk_text_layout_set_cursor_visible (priv->layout, TRUE);
- gtk_text_view_check_cursor_blink (text_view);
- }
+ if (cursor_visible (text_view) && priv->layout)
+ {
+ gtk_text_layout_set_cursor_visible (priv->layout, TRUE);
+ gtk_text_view_check_cursor_blink (text_view);
+ }
- g_signal_connect (gdk_display_get_keymap (gtk_widget_get_display (widget)),
- "direction-changed",
- G_CALLBACK (keymap_direction_changed), text_view);
- gtk_text_view_check_keymap_direction (text_view);
+ g_signal_connect (gdk_display_get_keymap (gtk_widget_get_display (widget)),
+ "direction-changed",
+ G_CALLBACK (keymap_direction_changed), text_view);
+ gtk_text_view_check_keymap_direction (text_view);
- if (priv->editable)
- {
- priv->need_im_reset = TRUE;
- gtk_im_context_focus_in (priv->im_context);
- }
+ if (priv->editable)
+ {
+ priv->need_im_reset = TRUE;
+ gtk_im_context_focus_in (priv->im_context);
}
- else
- {
- gtk_text_view_end_selection_drag (text_view);
+}
- gtk_widget_queue_draw (widget);
+static void
+gtk_text_view_focus_out (GtkWidget *widget)
+{
+ GtkTextView *text_view = GTK_TEXT_VIEW (widget);
+ GtkTextViewPrivate *priv = text_view->priv;
- DV(g_print (G_STRLOC": focus_out\n"));
+ gtk_text_view_end_selection_drag (text_view);
- if (cursor_visible (text_view) && priv->layout)
- {
- gtk_text_view_check_cursor_blink (text_view);
- gtk_text_layout_set_cursor_visible (priv->layout, FALSE);
- }
+ gtk_widget_queue_draw (widget);
- g_signal_handlers_disconnect_by_func (gdk_display_get_keymap (gtk_widget_get_display (widget)),
- keymap_direction_changed,
- text_view);
- gtk_text_view_selection_bubble_popup_unset (text_view);
+ DV(g_print (G_STRLOC": focus_out\n"));
- if (priv->text_handle)
- _gtk_text_handle_set_mode (priv->text_handle,
- GTK_TEXT_HANDLE_MODE_NONE);
+ if (cursor_visible (text_view) && priv->layout)
+ {
+ gtk_text_view_check_cursor_blink (text_view);
+ gtk_text_layout_set_cursor_visible (priv->layout, FALSE);
+ }
- if (priv->editable)
- {
- priv->need_im_reset = TRUE;
- gtk_im_context_focus_out (priv->im_context);
- }
+ g_signal_handlers_disconnect_by_func (gdk_display_get_keymap (gtk_widget_get_display (widget)),
+ keymap_direction_changed,
+ text_view);
+ gtk_text_view_selection_bubble_popup_unset (text_view);
+
+ if (priv->text_handle)
+ _gtk_text_handle_set_mode (priv->text_handle,
+ GTK_TEXT_HANDLE_MODE_NONE);
+
+ if (priv->editable)
+ {
+ priv->need_im_reset = TRUE;
+ gtk_im_context_focus_out (priv->im_context);
}
}
#include "gtkentryprivate.h"
#include "gtksearchentryprivate.h"
#include "gtkeventcontrollerkey.h"
+#include "gtkeventcontrollerfocus.h"
#include "gtkeventcontrollermotion.h"
#include "gtkeventcontrollerscroll.h"
#include "gtkframe.h"
guint keycode,
GdkModifierType state,
GtkTreeView *tree_view);
-static void gtk_tree_view_key_controller_focus_change (GtkEventController *key,
- GtkCrossingDirection direction,
+static void gtk_tree_view_focus_controller_focus_out (GtkEventController *focus,
GtkTreeView *tree_view);
static gint gtk_tree_view_focus (GtkWidget *widget,
G_CALLBACK (gtk_tree_view_key_controller_key_pressed), tree_view);
g_signal_connect (controller, "key-released",
G_CALLBACK (gtk_tree_view_key_controller_key_released), tree_view);
- g_signal_connect (controller, "focus-change",
- G_CALLBACK (gtk_tree_view_key_controller_focus_change), tree_view);
+ gtk_widget_add_controller (GTK_WIDGET (tree_view), controller);
+
+ controller = gtk_event_controller_focus_new ();
+ g_signal_connect (controller, "leave",
+ G_CALLBACK (gtk_tree_view_focus_controller_focus_out), tree_view);
gtk_widget_add_controller (GTK_WIDGET (tree_view), controller);
}
}
static void
-gtk_tree_view_key_controller_focus_change (GtkEventController *key,
- GtkCrossingDirection direction,
- GtkTreeView *tree_view)
+gtk_tree_view_focus_controller_focus_out (GtkEventController *focus,
+ GtkTreeView *tree_view)
{
- if (direction == GTK_CROSSING_OUT)
- {
- gtk_widget_queue_draw (GTK_WIDGET (tree_view));
+ gtk_widget_queue_draw (GTK_WIDGET (tree_view));
- if (tree_view->search_popover &&
- !gtk_event_controller_key_contains_focus (GTK_EVENT_CONTROLLER_KEY (key)))
- gtk_tree_view_search_popover_hide (tree_view->search_popover, tree_view,
- gtk_get_current_event_device ());
- }
+ if (tree_view->search_popover &&
+ !gtk_event_controller_focus_contains_focus (GTK_EVENT_CONTROLLER_FOCUS (focus)))
+ gtk_tree_view_search_popover_hide (tree_view->search_popover, tree_view,
+ gtk_get_current_event_device ());
}
/* Incremental Reflow
#include "gtktypebuiltins.h"
#include "gtkwidgetprivate.h"
#include "gtkgesturedrag.h"
+#include "gtkeventcontrollerfocus.h"
#include "gtkeventcontrollerkey.h"
#include "a11y/gtktreeviewaccessibleprivate.h"
static void
focus_in (GtkEventControllerKey *controller,
- GtkCrossingDirection direction,
GtkTreeViewColumn *column)
{
- if (direction == GTK_CROSSING_IN)
- _gtk_tree_view_set_focus_column (GTK_TREE_VIEW (column->priv->tree_view), column);
+ _gtk_tree_view_set_focus_column (GTK_TREE_VIEW (column->priv->tree_view), column);
}
/* Button handling code
gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_CAPTURE);
gtk_widget_add_controller (priv->button, controller);
- controller = gtk_event_controller_key_new ();
- g_signal_connect (controller, "focus-change", G_CALLBACK (focus_in), tree_column);
+ controller = gtk_event_controller_focus_new ();
+ g_signal_connect (controller, "enter", G_CALLBACK (focus_in), tree_column);
gtk_widget_add_controller (priv->button, controller);
priv->frame = gtk_frame_new (NULL);
#include "gtkcssshadowvalueprivate.h"
#include "gtkcssstylepropertyprivate.h"
#include "gtkdragdest.h"
+#include "gtkeventcontrollerfocus.h"
#include "gtkeventcontrollerkey.h"
#include "gtkeventcontrollermotion.h"
#include "gtkgesturedrag.h"
int height,
int baseline);
static gboolean gtk_window_close_request (GtkWindow *window);
-static void gtk_window_focus_change (GtkWidget *widget,
- GtkCrossingDirection direction);
+static void gtk_window_focus_in (GtkWidget *widget);
+static void gtk_window_focus_out (GtkWidget *widget);
static gboolean gtk_window_key_pressed (GtkWidget *widget,
guint keyval,
guint keycode,
GtkCssNode *widget_node;
GdkSeat *seat;
GtkEventController *motion_controller;
+ GtkEventController *controller;
#ifdef GDK_WINDOWING_X11
GtkDropTarget *dest;
#endif
priv->key_controller = gtk_event_controller_key_new ();
gtk_event_controller_set_propagation_phase (priv->key_controller, GTK_PHASE_CAPTURE);
- g_signal_connect_swapped (priv->key_controller, "focus-change",
- G_CALLBACK (gtk_window_focus_change), window);
g_signal_connect_swapped (priv->key_controller, "key-pressed",
G_CALLBACK (gtk_window_key_pressed), window);
g_signal_connect_swapped (priv->key_controller, "key-released",
G_CALLBACK (gtk_window_key_released), window);
gtk_widget_add_controller (widget, priv->key_controller);
+ controller = gtk_event_controller_focus_new ();
+ g_signal_connect_swapped (controller, "enter",
+ G_CALLBACK (gtk_window_focus_in), window);
+ g_signal_connect_swapped (controller, "leave",
+ G_CALLBACK (gtk_window_focus_out), window);
+ gtk_widget_add_controller (widget, controller);
/* Shared constraint solver */
priv->constraint_solver = gtk_constraint_solver_new ();
}
static void
-gtk_window_focus_change (GtkWidget *widget,
- GtkCrossingDirection direction)
+gtk_window_focus_in (GtkWidget *widget)
{
GtkWindow *window = GTK_WINDOW (widget);
- if (direction == GTK_CROSSING_IN)
+ /* It appears spurious focus in events can occur when
+ * the window is hidden. So we'll just check to see if
+ * the window is visible before actually handling the
+ * event
+ */
+ if (gtk_widget_get_visible (widget))
{
- /* It appears spurious focus in events can occur when
- * the window is hidden. So we'll just check to see if
- * the window is visible before actually handling the
- * event
- */
- if (gtk_widget_get_visible (widget))
- {
- _gtk_window_set_is_active (window, TRUE);
+ _gtk_window_set_is_active (window, TRUE);
- if (gtk_window_has_mnemonic_modifier_pressed (window))
- _gtk_window_schedule_mnemonics_visible (window);
- }
+ if (gtk_window_has_mnemonic_modifier_pressed (window))
+ _gtk_window_schedule_mnemonics_visible (window);
}
- else
- {
- _gtk_window_set_is_active (window, FALSE);
+}
- /* set the mnemonic-visible property to false */
- gtk_window_set_mnemonics_visible (window, FALSE);
- }
+static void
+gtk_window_focus_out (GtkWidget *widget)
+{
+ GtkWindow *window = GTK_WINDOW (widget);
+
+ _gtk_window_set_is_active (window, FALSE);
+
+ /* set the mnemonic-visible property to false */
+ gtk_window_set_mnemonics_visible (window, FALSE);
}
static void
'gtkentrybuffer.c',
'gtkentrycompletion.c',
'gtkeventcontroller.c',
+ 'gtkeventcontrollerfocus.c',
'gtkeventcontrollerkey.c',
'gtkeventcontrollerlegacy.c',
'gtkeventcontrollermotion.c',
}
static void
-focus_change (GtkEventControllerKey *key,
- GtkCrossingDirection direction,
- GString *s)
+focus_in (GtkEventControllerFocus *key,
+ GString *s)
{
GtkWidget *widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (key));
- g_string_append_printf (s, "%s: focus-change %s is-focus: %d contains-focus: %d\n",
+ g_string_append_printf (s, "%s: focus-in is-focus: %d contains-focus: %d\n",
widget_name (widget),
- direction == GTK_CROSSING_IN ? "in" : "out",
- gtk_event_controller_key_is_focus (key),
- gtk_event_controller_key_contains_focus (key));
+ gtk_event_controller_focus_is_focus (key),
+ gtk_event_controller_focus_contains_focus (key));
+}
+
+static void
+focus_out (GtkEventControllerFocus *key,
+ GString *s)
+{
+ GtkWidget *widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (key));
+
+ g_string_append_printf (s, "%s: focus-out is-focus: %d contains-focus: %d\n",
+ widget_name (widget),
+ gtk_event_controller_focus_is_focus (key),
+ gtk_event_controller_focus_contains_focus (key));
}
static void
{
GtkEventController *controller;
- controller = gtk_event_controller_key_new ();
- g_signal_connect (controller, "focus-change", G_CALLBACK (focus_change), s);
+ controller = gtk_event_controller_focus_new ();
+ g_signal_connect (controller, "enter", G_CALLBACK (focus_in), s);
+ g_signal_connect (controller, "leave", G_CALLBACK (focus_out), s);
gtk_widget_add_controller (widget, controller);
}
g_print ("-> box\n%s\n", s->str);
g_assert_cmpstr (s->str, ==,
-"window: focus-change in is-focus: 0 contains-focus: 1\n"
-"box: focus-change in is-focus: 1 contains-focus: 1\n"
+"window: focus-in is-focus: 0 contains-focus: 1\n"
+"box: focus-in is-focus: 1 contains-focus: 1\n"
);
g_string_truncate (s, 0);
g_print ("box -> entry1\n%s\n", s->str);
g_assert_cmpstr (s->str, ==,
-"box: focus-change out is-focus: 0 contains-focus: 0\n"
-"window: focus-change out is-focus: 0 contains-focus: 0\n"
-"window: focus-change in is-focus: 0 contains-focus: 1\n"
-"box: focus-change in is-focus: 0 contains-focus: 1\n"
-"box1: focus-change in is-focus: 0 contains-focus: 1\n"
-"entry1: focus-change in is-focus: 1 contains-focus: 1\n"
+"box: focus-out is-focus: 0 contains-focus: 0\n"
+"window: focus-out is-focus: 0 contains-focus: 0\n"
+"window: focus-in is-focus: 0 contains-focus: 1\n"
+"box: focus-in is-focus: 0 contains-focus: 1\n"
+"box1: focus-in is-focus: 0 contains-focus: 1\n"
+"entry1: focus-in is-focus: 1 contains-focus: 1\n"
);
g_string_truncate (s, 0);
g_print ("entry1 -> entry2\n%s\n", s->str);
g_assert_cmpstr (s->str, ==,
-"entry1: focus-change out is-focus: 0 contains-focus: 0\n"
-"box1: focus-change out is-focus: 0 contains-focus: 0\n"
-"box: focus-change out is-focus: 0 contains-focus: 0\n"
-"window: focus-change out is-focus: 0 contains-focus: 0\n"
-"window: focus-change in is-focus: 0 contains-focus: 1\n"
-"box: focus-change in is-focus: 0 contains-focus: 1\n"
-"box2: focus-change in is-focus: 0 contains-focus: 1\n"
-"entry2: focus-change in is-focus: 1 contains-focus: 1\n"
+"entry1: focus-out is-focus: 0 contains-focus: 0\n"
+"box1: focus-out is-focus: 0 contains-focus: 0\n"
+"box: focus-out is-focus: 0 contains-focus: 0\n"
+"window: focus-out is-focus: 0 contains-focus: 0\n"
+"window: focus-in is-focus: 0 contains-focus: 1\n"
+"box: focus-in is-focus: 0 contains-focus: 1\n"
+"box2: focus-in is-focus: 0 contains-focus: 1\n"
+"entry2: focus-in is-focus: 1 contains-focus: 1\n"
);
g_string_truncate (s, 0);
g_print ("entry2 -> box\n%s", s->str);
g_assert_cmpstr (s->str, ==,
-"entry2: focus-change out is-focus: 0 contains-focus: 0\n"
-"box2: focus-change out is-focus: 0 contains-focus: 0\n"
-"box: focus-change out is-focus: 0 contains-focus: 0\n"
-"window: focus-change out is-focus: 0 contains-focus: 0\n"
-"window: focus-change in is-focus: 0 contains-focus: 1\n"
-"box: focus-change in is-focus: 1 contains-focus: 1\n"
+"entry2: focus-out is-focus: 0 contains-focus: 0\n"
+"box2: focus-out is-focus: 0 contains-focus: 0\n"
+"box: focus-out is-focus: 0 contains-focus: 0\n"
+"window: focus-out is-focus: 0 contains-focus: 0\n"
+"window: focus-in is-focus: 0 contains-focus: 1\n"
+"box: focus-in is-focus: 1 contains-focus: 1\n"
);
g_string_truncate (s, 0);